package org.p2psimulator.entity.protocol.unstructured.gnutellacycles;

import java.util.List;

import org.p2psimulator.entity.Id;
import org.p2psimulator.entity.Message;
import org.p2psimulator.entity.Peer;
import org.p2psimulator.entity.protocol.messages.MessageTypes;
import org.p2psimulator.entity.protocol.messages.general.QueryMessage;
import org.p2psimulator.engine.Environment;
import org.p2psimulator.entity.overlaynetwork.FloodOverlay;
import org.p2psimulator.util.SystemLogger;

public class GnutellaQueryCycle extends GnutellaCycle {

    private Id queryKey;

    public GnutellaQueryCycle(Environment env, int transId) {
        super(env, transId);
    }

    @Override
    public String runRequestCycle(Peer p) {
        StringBuilder ret = new StringBuilder();
        int querySent = 0;

        FloodOverlay overlay = null;

        try {
            overlay = (FloodOverlay) env.getFloodOverlayNetwork();
        } catch (Exception e) {
            SystemLogger.enviromentLogger.error(e.getMessage());
            e.printStackTrace();
            return "";
        }

        queryKey = env.getFileSystem().getRandomFileId();
        Object[] array = overlay.getPeerNeighbors(p.getId()).getNeighbors().toArray();
        for (Object o : array) {
            Id id = (Id) o;
            QueryMessage query = new QueryMessage(p.getId(), id,
                    this.currentTransactionId, p.getBehavior().getBehaviorType());
            query.setTTL(7);
            query.setHOP(0);
            query.setKey(queryKey);
            query.setServentId(p.getId());

            p.getRoutingMessagesMap().put(currentTransactionId,
                    query.getOrigin());
            p.getProcessedMessages().add(query.getMessageId());

            env.getNetwork().sendMessage(query);
            querySent++;
        }

        ret.append(" [ QUERY REQUEST CYCLE - QUERIES ENVIADAS: " + querySent + " ]");
        ret.append(" [ KEYWORD: " + queryKey.getValue() + " ]");
        return ret.toString();
    }

    @Override
    public String runResponseCycle(Peer p) {
        StringBuilder ret = new StringBuilder();
        List<Message> queryhits = p.getMessageStack().get(
                MessageTypes.QUERY_HIT_MESSAGE.getName());


        if (queryhits != null && queryhits.size() > 0) {
            ret.append("[ QUERY RESPONSE CYCLE - QUERY HITS RECEBIDAS: " + queryhits.size() + " ]");

        } else {
            ret.append("[ QUERY RESPONSE CYCLE - QUERY HITS RECEBIDAS: 0 ]");
        }

        return ret.toString();
    }

    @Override
    public String runSecondRequestCycle(Peer p) {
        // TODO Auto-generated method stub
        return "";
    }

    @Override
    public String runSecondResponseCycle(Peer p) {
        // TODO Auto-generated method stub
        return "";
    }

    public Id getQueryKey() {
        return queryKey;
    }

    public void setQueryKey(Id queryKey) {
        this.queryKey = queryKey;
    }
}
